package zgame.main;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

import org.apache.log4j.Logger;

import zgame.bean.Port;
import zgame.socket.DataPackage;
import zgame.socket.DataReceiveListener;
import zgame.socket.ServerConnection;
import zgame.socket.handle.ClientRequestHandle;

public class Main {
  private static Logger log = Logger.getLogger(Main.class);
  
  private static boolean isRunning = true;
  public static ServiceController serviceController;
  
  public static void main(String[] args) {
    ServerSocket servSock = null;
    try {
      Initialize.loadConfig();
      Initialize.initForDB();
      Initialize.loadImageToCatche("res");
      Initialize.loadAvatarToCatche("avatars");
      Initialize.initForCache();
      
      // Start job to reload config sequence
      Global.reloadConfigJob.setDelay(Global.RELOAD_CONFIG_INTERVAL).start();

      Port authenticatePort = Global.currentServiceInfo.getPort(Constants.AUTHENTICATE_PORT_NAME);
      servSock = new ServerSocket(authenticatePort.getValue());

      serviceController = new ServiceController();
      serviceController.start();

      log.info("-------------------------------------------------------");
      log.info("AUTHENTICATE SERVER WAS STARTED AT PORT " + authenticatePort.getValue());
      log.info("-------------------------------------------------------");
    } catch (Exception e) {
      log.error("Server can't start.Please check your config file ", e);
      isRunning = false;
      return;
    }

    // Listening
    while (isRunning) {
      try {
        Socket clientSocket = servSock.accept();
        ServerConnection connection = new ServerConnection(clientSocket);
        new AddRequestToPoolListener().setServerConnection(connection);
        Global.notAuthenConnectionList.add(connection);
      } catch (IOException e) {
        log.warn("Accept client fail", e);
      }
    }
  }

  public boolean isRunning() {
    return isRunning;
  }

  public void stop() {
    isRunning = false;
    // TODO: stop all current connection when server stop
  }
  
  static class AddRequestToPoolListener implements DataReceiveListener {
    private ServerConnection serverConnection;
    
    public void setServerConnection(ServerConnection serverConnection) {
      this.serverConnection = serverConnection;
      if (serverConnection != null) {
        serverConnection.setListener(this);  
      }
    }

    @Override
    public void onConnectDone() {
    }

    @Override
    public void onConnectFail() {
    }

    @Override
    public void onDisconnect() {
    }

    @Override
    public void onRecieveData(DataPackage dataPackage) {
      RequestManager.instance().addRequest(new ClientRequestHandle(serverConnection, dataPackage));
    }
  }
}
